<!doctype html>
<html>
  <head>
    <title>Transform拖动示例</title>
    <style>
      .draggable {
        width: 100px;
        height: 100px;
        background: red;
        border-radius: 100%;
        color: white;
        font-weight: bold;
        display: flex;
        align-items: center;
        justify-content: center;
        cursor: move;
        user-select: none; /* 防止拖动时选中文本 */
        position: absolute; /* 脱离文档流，避免影响其他元素 */
      }
    </style>
  </head>
  <body>
    <div class="draggable" id="dragElement">拖动我</div>

    <script>
      const draggableElement = document.getElementById("dragElement");
      let isDragging = false;
      let startX, startY;
      let initialTranslateX = 0,
        initialTranslateY = 0;

      // 获取元素当前的translate值
      function getCurrentTranslate(element) {
        const style = window.getComputedStyle(element);
        const matrix = new DOMMatrix(style.transform);
        return { x: matrix.e, y: matrix.f }; // matrix.e是translateX，matrix.f是translateY
      }

      // 开始拖动
      function startDrag(e) {
        isDragging = true;
        const touch = e.type.startsWith("touch") ? e.touches[0] : e;

        // 记录初始鼠标/触摸位置
        startX = touch.clientX;
        startY = touch.clientY;

        // 获取元素当前的translate值
        const currentTranslate = getCurrentTranslate(draggableElement);
        initialTranslateX = currentTranslate.x;
        initialTranslateY = currentTranslate.y;

        // 添加移动和结束事件监听
        document.addEventListener("mousemove", handleDrag);
        document.addEventListener("touchmove", handleDrag, { passive: false }); // passive:false允许阻止默认行为
        document.addEventListener("mouseup", stopDrag);
        document.addEventListener("mouseleave", stopDrag);
        document.addEventListener("touchend", stopDrag);
      }

      // 拖动中
      function handleDrag(e) {
        if (!isDragging) return;
        e.preventDefault(); // 防止触摸时页面滚动

        const touch = e.type.startsWith("touch") ? e.touches[0] : e;
        const currentX = touch.clientX;
        const currentY = touch.clientY;

        // 计算位移差
        const deltaX = currentX - startX;
        const deltaY = currentY - startY;

        // 更新transform
        draggableElement.style.transform = `translate(${initialTranslateX + deltaX}px, ${initialTranslateY + deltaY}px)`;
      }

      // 结束拖动
      function stopDrag() {
        isDragging = false;
        // 移除事件监听
        document.removeEventListener("mousemove", handleDrag);
        document.removeEventListener("touchmove", handleDrag);
        document.removeEventListener("mouseup", stopDrag);
        document.removeEventListener("mouseleave", stopDrag);
        document.removeEventListener("touchend", stopDrag);
      }

      // 添加开始拖动事件监听
      draggableElement.addEventListener("mousedown", startDrag);
      draggableElement.addEventListener("touchstart", startDrag);
    </script>
  </body>
</html>
